#include "seqList.h"
SeqList *createSeqList(int n) {
    // 申请表头
    SeqList *seqList = (SeqList *)malloc(sizeof(SeqList));
    if (seqList == NULL) {
        printf("malloc header failed!\n");
        return NULL;
    }
    // 初始化表头的每个成员
    seqList->data = (Element *) malloc(sizeof(Element) * n);
    if (seqList->data == NULL) {
        return NULL;
    }
    seqList->len = 0;
    seqList->capacity = n;

    return seqList;
}

void releaseSeqList(SeqList *seq) {
    if (seq) {
        if (seq->data) {
            free(seq->data);
        }
        free(seq);
    }
}

/* 扩容的方法，设置为静态方法 */
static int enLargerSeq(SeqList *seq) {
    // 1. 先申请一块更大的空间，空间大小建议是原空间的2倍大小
    Element *tmp = malloc(sizeof(Element) * seq->capacity * 2);
    if (tmp == NULL) {
        return -1;
    }
    // 2. 把原空间的内容拷贝到新空间
    for (int i = 0; i < seq->len; ++i) {
        tmp[i] = seq->data[i];
    }
    // 3. 释放原空间，更新表头的指针指向新空间
    free(seq->data);
    seq->data = tmp;
    seq->capacity *= 2;
    printf("enLarger!\n");
    return 0;
}

// A && B
int pushBackSeq(SeqList *seq, Element val) {
    // 判断是否溢出，如果溢出，要扩容
    if ((seq->len >= seq->capacity) && enLargerSeq(seq) ) {
        return -1;
    }
    // 放入新元素
    seq->data[seq->len] = val;
    ++seq->len;
    return 0;
}

void showSeqList(SeqList *seq) {
    for (int i = 0; i < seq->len; ++i) {
        printf("%d\t", seq->data[i]);
    }
    printf("\n");
}

/* 下标的索引值的取值范围
 * pos : [1, 2, 3, 4]	物理世界
 * 	   : [0, 1, 2, 3]	C语言
 * */
int insertSeq(SeqList *seq, int pos, Element val) {
    // 1. 范围校验 check
    if (pos < 0 || pos > seq->len) {
        printf("pos invalid!\n");
        return -1;
    }
    // 2. 是否扩容
    if ((seq->len >= seq->capacity) && enLargerSeq(seq) ) {
        return -1;
    }
    // 3. 从后往前，依次向后拷贝元素，[pos...len-1]移动
    for (int i = seq->len -1; i >= pos; --i) {
        seq->data[i + 1] = seq->data[i];
    }
    // 4. 放入新元素，更新表头
    seq->data[pos] = val;
    ++seq->len;

    return 0;
}

int deleteSeq(SeqList *seq, Element val) {
    // 1. 找到val所在的下标[索引值]
    int pos = findSeq(seq, val);
    if (pos == -1) {
        return -1;
    }
    // 2. 删除这个下标的值，其实就是后面的元素把当前的元素覆盖，依次向前覆盖
    for (int i = pos + 1; i < seq->len; ++i) {
        seq->data[i - 1] = seq->data[i];
    }
    --seq->len;
    return 0;
}

// 找到第一个所在位置，就返回，如果没有找到，返回-1
int findSeq(SeqList *seq, Element val) {
    for (int i = 0; i < seq->len; ++i) {
        if (seq->data[i] == val) {
            return i;
        }
    }
    return -1;
}
